//
//  main.c
//  LC3Compiler
//
//  Created by Anthony Sierra on 5/31/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//
/*
 Function Numbers:
 1 = ADD
 2 = AND
 */


#include <stdio.h>
#include <ctype.h>
#include "TheSecondPass.h"
#include "ArrayList.h"
/*
 Global Variables-----------------
 */
FILE *fr, *output_file;
int *statements;
ArrayList word_library;
short origin = 0;
int program_counter = 0;

//Functions----------------------
int command(const char *message);
void addFunction(char *first);
void andFunction(char *first);
void addSyntaxCheck(const char *first);
void andSyntaxCheck(const char *first);
void brSyntaxCheck(char *first);
void ldSyntaxCheck(char *first);
void ldrSyntaxCheck(char *first);
void notSyntaxCheck(char *first);
void trapSyntaxCheck(char *first);
void origSyntaxCheck(char *first);
void fillSyntaxCheck(char *first);
void blkwSyntaxCheck(char *first);
void stringzSyntaxCheck(char *first);
int checkSymbols(char *word);
int checkDictionary(char *word);
void brFunction(char *first);
void jmpFunction(char *first);
void jsrFunction(char *first);
void jsrrFunction(char *first);
void ldFunction(char *first);
void ldiFunction(char *first);
void ldrFunction(char *first);
void leaFunction(char *first);
void notFunction(char *first);
void retFunction(char *first);
void rtiFunction(char *first);
void stFunction(char *first);
void stiFunction(char *first);
void strFunction(char *first);
void trapFunction(char *first);
void pushFunction(char *first);
void popFunction(char *first);
void negFunction(char *first);
void origFunction(char *first);
void blkwFunction(char *first);
void stringzFunction(char *first);
void fillFunction(char *first);
char* getObjFilename (char filename[]);
char words[35][20];

int main (int argc, const char * argv[])
{
    //Make integer program counter for counting where we are in the file.
    
    strcpy(words[0], "ADD");
    strcpy(words[1], "AND");
    strcpy(words[2], "BR");
    strcpy(words[3], "JMP");
    strcpy(words[4], "JSR");
    strcpy(words[5], "JSRR");
    strcpy(words[6], "LD");
    strcpy(words[7], "LDI");
    strcpy(words[8], "LDR");
    strcpy(words[9], "LEA");
    strcpy(words[10], "NOT");
    strcpy(words[11], "RET");
    strcpy(words[12], "RTI");
    strcpy(words[13], "ST");
    strcpy(words[14], "STI");
    strcpy(words[15], "STR");
    strcpy(words[16], "TRAP");
    strcpy(words[17], "PUSH");
    strcpy(words[18], "POP");
    strcpy(words[19], "NEG");
    strcpy(words[20], ".ORIG");
    strcpy(words[21], ".FILL");
    strcpy(words[22], ".BLKW");
    strcpy(words[23], ".STRINGZ");
    strcpy(words[24], ".END");
    strcpy(words[25], "GETC");
    strcpy(words[26], "PUTS");
    strcpy(words[27], "HALT");
    strcpy(words[28], "OUT");
    strcpy(words[29], "IN");
    strcpy(words[30], "PUTSP");
    
    //Library of words in the program.
    initializeArrayList(&word_library);
    /*
    new.name = "Wasup";
    new.line_number = 4;
    addItemToEndOfArrayList(&word_library, new);
    new.name = "Waasdfsup";
    new.line_number = 6;
    addItemToEndOfArrayList(&word_library, new);
    printf("%s", getItem(&word_library, 0).name);
    printf("%s", getItem(&word_library, 1).name);*/
    
    
    //Variable for reading.
    char message[30];
    
    char filename[FILENAME_MAX];
    printf("Enter the filename to compile: ");
    gets(filename);
    //infile = fopen(filename, "r"); 
    fr = fopen(filename, "rw"); 
    if (fr == NULL) {
        printf("File %s not found!", filename);
        //exit();
    }
    
    //Setup the file that we are outputting to.
    output_file = fopen(strcat(filename, ".obj"), "wb");    //Open the file for reading and compiling
    
    
    //Check to make sure the file that was opened was readable.
    if (fr == NULL) {
        printf("Couldnt open text\n");
        exit(1);
    }
    //Check to make sure the file to output to was created or exists.
    if (output_file == NULL) {
        printf("Couldnt Open or Create Output file\n");
        exit(1);
    }
    
    /*
     Get the Origin of the File
     */
    fscanf(fr, "%30s", message);
    //if there is anything that is not .ORIG then ouput error and poop out.
    if (strcmp(message, ".ORIG") > 0 || strcmp(message, ".ORIG") < 0)
    {
        printf(".ORIG expected but found %s", message);
        exit(1);
    }
    /*
     Get the starting value of the origin.
     */
    fscanf(fr, "%s", message);
    if (message[0] == 'x')
    {
        char temp[30];
        int length = 0;
        while (message[length] != '\0')
        {
            length++;
        }
        for (int i = 0; i<= length; i++)
        {
            temp[i] = message[i+1];
        }
        //set origin to the passed in number
        sscanf(temp, "%x", &origin);
    }
    else
    {
        //set origin to the passed in number
        sscanf(message, "%X", &origin);
    }
    if (origin < 0x0200 || origin > 0xFE00)
    {
        if (origin == 0) {
            printf("Please put 0 in front of x\n");
        }
        else {
            printf("Expected Valid Hex value instead got %d\n", origin);
        }
    }
    
    
    
    
    
    
    
    char stuff[40];
    int done = 0;
    /*
     This would be for the first pass
     */
    while (fgets(stuff, 40, fr) && stuff != EOF && !done) {
        int i = 0;
        char upper_case_string[30];
        while(stuff[i])
        {
            upper_case_string[i] = toupper(stuff[i]);
            i++;
        }
        char *first;
        first = strtok(stuff, " ,;\n");
        while (first != NULL) {
            if (!strcmp(first, words[24])) { //IF .END
                done = 1;
                break;
            }
            if (checkDictionary(first))
            {
                //if ADD
                if (!strcmp(first, words[0]))
                {
                    addSyntaxCheck(first);
                }//end if
    
                else if (!strcmp(first, words[1])) { //if AND
                    andSyntaxCheck(first);
                }
                else if (first[0] == 'B' && first[1] == 'R') { //if BR
                    brSyntaxCheck(first);
                }
                else if (!strcmp(first, words[3])) { // If JMP
                    first = strtok(NULL, " ,;\n");
                    char integer[30];
                    int length = 0;
                    while (first[length+1] != '\0')
                    {
                        integer[length] = first[length+1];
                        length++;
                    }
                    integer[length] = '\0';
                    
                    if(strlen(first) != 2) {
                        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
                    }
                    int number = atoi(integer);
                    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
                }
                else if (!strcmp(first, words[4])) { //If JSR
                    first = strtok(NULL, " ,;");
                    //get rid of \n at end if there is one.
                    int len = (int)strlen(first);
                    if (first[len-1] == '\n') {
                        first[len-1] = '\0';
                    }
                    if (!checkSymbols(first)) {
                        printf("Unspecified Symbol %s at Line Number %d\n", first, program_counter);
                    }
                    
                }
                else if (!strcmp(first, words[5])) { // If JSRR
                    first = strtok(NULL, " ,;\n");
                    char integer[30];
                    int length = 0;
                    while (first[length+1] != '\0')
                    {
                        integer[length] = first[length+1];
                        length++;
                    }
                    integer[length] = '\0';
                    if(strlen(first) != 2) {
                        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
                    }
                    
                    int number = atoi(integer);
                    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
                }
                else if (!strcmp(first, words[6])) { //If LD
                    ldSyntaxCheck(first);
                }
                else if (!strcmp(first, words[7])) { //If LDI
                    ldSyntaxCheck(first);
                }
                else if (!strcmp(first, words[8])) { //IF LDR
                    ldrSyntaxCheck(first);
                }
                else if (!strcmp(first, words[9])) { //IF LEA
                    ldSyntaxCheck(first);
                }
                else if (!strcmp(first, words[10])) { //If NOT
                    notSyntaxCheck(first);
                }
                else if (!strcmp(first, words[11])) { //If RET
                }
                else if (!strcmp(first, words[12])) { //If RTI
                }
                else if (!strcmp(first, words[13])) { //If ST
                    ldSyntaxCheck(first);
                }
                else if (!strcmp(first, words[14])) { //If STI
                    ldSyntaxCheck(first);
                }
                else if (!strcmp(first, words[15])) { //If STR
                    ldrSyntaxCheck(first);
                }
                else if (!strcmp(first, words[16])) { //IF TRAP
                    trapSyntaxCheck(first);
                }
                else if (!strcmp(first, words[17])) { //IF PUSH
                    first = strtok(NULL, " ,;\n");
                    char integer[30];
                    int length = 0;
                    while (first[length+1] != '\0')
                    {
                        integer[length] = first[length+1];
                        length++;
                    }
                    integer[length] = '\0';
                    if(strlen(first) != 2) {
                        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
                    }
                    
                    int number = atoi(integer);
                    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
                }
                else if (!strcmp(first, words[18])) { //IF POP
                    first = strtok(NULL, " ,;\n");
                    char integer[30];
                    int length = 0;
                    while (first[length+1] != '\0')
                    {
                        integer[length] = first[length+1];
                        length++;
                    }
                    integer[length] = '\0';
                    if(strlen(first) != 2) {
                        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
                    }
                    
                    int number = atoi(integer);
                    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
                }
                else if (!strcmp(first, words[19])) {// IF NEG
                    first = strtok(NULL, " ,;\n");
                    char integer[30];
                    int length = 0;
                    while (first[length+1] != '\0')
                    {
                        integer[length] = first[length+1];
                        length++;
                    }
                    integer[length] = '\0';
                    if(strlen(first) != 2) {
                        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
                    }
                    
                    int number = atoi(integer);
                    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
                    first = strtok(NULL, " ,;\n");
                    length = 0;
                    while (first[length+1] != '\0')
                    {
                        integer[length] = first[length+1];
                        length++;
                    }
                    integer[length] = '\0';
                    if(strlen(first) != 2) {
                        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
                    }
                    
                    number = atoi(integer);
                    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
                }
                else if (!strcmp(first, words[20])) { //IF .ORIG
                    origSyntaxCheck(first);
                }
                else if (!strcmp(first, words[21])) { //IF .FILL
                    fillSyntaxCheck(first);
                }
                else if (!strcmp(first, words[22])) { //IF .BLKW
                    blkwSyntaxCheck(first);
                }
                else if (!strcmp(first, words[23])) { //IF .STRINGZ
                    stringzSyntaxCheck(first);
                }
            }
            else {
                Symbol *label = (Symbol*)malloc(sizeof(Symbol));
                label->name = (char*)malloc(30*sizeof(char));
                strcpy(label->name, first);
                label->line_number = program_counter;
                //printf("%d\n", &label->name);
                if (checkSymbols(label->name)) {
                    printf("Already specified name %s found on line %d", first, program_counter);
                } else {
                    addItemToEndOfArrayList(&word_library, label);
                }
            }
            first = strtok(NULL, " ,;\n");
        }//end while
        program_counter++;
    }
    fclose(fr);
    
    /**-------------------------------------------------------------------------
     This IS PASS TWO-----------------------------------------------------------
     --------------------------------------------------------------------------*/
    //Open the file for reading and compiling
    fr = fopen("/Users/anthonysierra/Documents/School/Machine Organization/LC3Compiler/LC3Compiler/TextFile.txt", "rw");
    char fileRead[40];
    program_counter = 0;
    done = 0;
    //Write the origin of the file.
    origin = origin >> 8 | origin << 8;
    fwrite(&origin, sizeof(short), 1, output_file);
    while (fgets(fileRead, 40, fr) && fileRead != EOF && done == 0) {
        int i = 0;
        char upper_case_string[30];
        while(stuff[i])
        {
            upper_case_string[i] = toupper(fileRead[i]);
            i++;
        }
        char *first;
        first = strtok(fileRead, " ,;\n");
        while (first != NULL && done == 0) {
            if (!strcmp(first, words[24])) { //IF .END
                done = 1;
                break;
            }
            else if(!strcmp(first, words[25])) { //GETC
                trapFunction("20");
            }
            else if(!strcmp(first, words[26])) { //PUTS
                trapFunction("22");
            }
            else if(!strcmp(first, words[27])) { //HALT
                trapFunction("25");
            }
            else if(!strcmp(first, words[28])) { //OUT
                trapFunction("21");
            }
            else if(!strcmp(first, words[29])) { //IN
                trapFunction("23");
            }
            else if(!strcmp(first, words[30])) { //PUTSP
                trapFunction("24");
            }
            if (checkDictionary(first)) {
                if (!strcmp(first, words[0])) { //If ADD
                    addFunction(first);
                    
                }
                else if (!strcmp(first, words[1])) { //AND
                    andFunction(first);
                }  
                else if (!strcmp(first, words[2])) {//BR
                    brFunction(first);
                }
                else if(!strcmp(first, words[3])) { //JMP
                    jmpFunction(first);
                } 
                else if(!strcmp(first, words[4])) { //JSR
                    jsrFunction(first);
                } else if(!strcmp(first, words[5])) { //JSRR
                    jsrrFunction(first);
                } else if(!strcmp(first, words[6])) { //LD
                    ldFunction(first);
                } else if(!strcmp(first, words[7])) { //LDI
                    ldiFunction(first);
                }else if(!strcmp(first, words[8])) { //LDR
                    ldrFunction(first);
                }else if(!strcmp(first, words[9])) { //LEA
                    leaFunction(first);
                }else if(!strcmp(first, words[10])) { //NOT
                    notFunction(first);
                } else if(!strcmp(first, words[11])) { //RET
                    retFunction(first);
                } else if(!strcmp(first, words[12])) { //RTI
                    rtiFunction(first);
                }else if(!strcmp(first, words[13])) { //ST
                    stFunction(first);
                } else if(!strcmp(first, words[14])) { //STI
                    stiFunction(first);
                }else if(!strcmp(first, words[15])) { //STR
                    strFunction(first);
                } else if(!strcmp(first, words[16])) { //TRAP
                    trapFunction(first);
                } else if(!strcmp(first, words[17])) { //PUSH
                    pushFunction(first);
                } else if(!strcmp(first, words[18])) { //POP
                    popFunction(first);
                } else if(!strcmp(first, words[19])) { //NEG
                    negFunction(first);
                } else if(!strcmp(first, words[20])) { //.ORIG
                    origFunction(first);
                } else if(!strcmp(first, words[21])) { //.FILL
                    fillFunction(first);
                } else if(!strcmp(first, words[22])) { //.BLKW
                    blkwFunction(first);
                } else if(!strcmp(first, words[23])) { //.STRINGZ
                    stringzFunction(first);
                } 
            }
            //move string forward
            first = strtok(NULL, " ,;");
        }
        program_counter++;
    }
    fclose(output_file);
    
    
    return 0;
}
/**
 Goes through array of Symbols made by user and returns a one if
 the label has been previously made. Else returns 0;
 */
int checkSymbols(char *word) {
    int result = 0;
    for (int i = 0; i < getSize(&word_library); i++) {
        if (strcmp(getItem(&word_library, i)->name, word) == 0) {
            result = 1;
            break;
        }
    }
    return result;
}
int checkDictionary(char *word)
{
    int result = 0;
    for (int i = 0; i < 25; i++) {
        if(!strcmp(word, words[i]))
           {
               result = 1;
               break;
           }
        if (word[0] == 'B' && word[1] == 'R') {
            result = 1;
            break; 
        }
    }
    return result;
}
void setup()
{
    
}
/*
 This checks to see what command was issued.
 */
int command(const char *message)
{
    int ret_val = 0;
    if (!strcmp(message, "ADD") || !strcmp(message, "ADD,"))
    {
        ret_val = 1;
    }
    else if (!strcmp(message, "AND") || !strcmp(message, "AND,"))
    {
        ret_val = 2;
    }
    return ret_val;
}
void addSyntaxCheck(const char *first)
{
    first = strtok(NULL, " ,;");
    char integer[30];
    int length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    
    int number = atoi(integer);
    
    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    first = strtok(NULL, " ,;");
    length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    number = atoi(integer);
    
    if (first[0] != 'R'|| number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    first = strtok(NULL, " ,;\n");
    length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    number = atoi(integer);
    
    if (first[0] == 'R')
    {
        if (number < 0 || number > 7 ) {printf("Expected R0-7 or # but found %s at Line Number: %d\n", first, program_counter);}
    }
    else if (first[0] == '#')
    {
        char *integer = strtok(first, "#");
        int number = atoi(integer);
        if (number < -16 || number > 15) { printf("%d cannot be represented as a signed number in 5 bits  at Line Number: %d", number, program_counter);}//end #
    }//end else if
}
void andSyntaxCheck(const char *first) {
    first = strtok(NULL, " ,;");
    char integer[30];
    int length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    
    int number = atoi(integer);
    
    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    first = strtok(NULL, " ,;");
    length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    number = atoi(integer);
    
    if (first[0] != 'R'|| number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    first = strtok(NULL, " ,;\n");
    length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    number = atoi(integer);
    
    if (first[0] == 'R')
    {
        if (number < 0 || number > 7 ) {printf("Expected R0-7 or # but found %s at Line Number: %d\n", first, program_counter);}
    }
    else if (first[0] == '#')
    {
        char *integer = strtok(first, "#");
        int number = atoi(integer);
        if (number < -16 || number > 15) { printf("%d cannot be represented as a signed number in 5 bits  at Line Number: %d", number, program_counter);}//end #
    }//end else if
}
void brSyntaxCheck(char *first)
{
    char thing[4];
    int i = 0;
    while (first[i+2])
    {
        thing[i] = first[i+2];
        i++;
    }
    thing[i] = '\0';
    if (thing[0] == 'n')
    {
        if (thing[1] == 'z') {
            if (thing[2] == 'p') {
                if (thing[3] != '\0') {
                    printf("Error BRnzp or varient expected else got %s", first);
                }
            }
            else if (thing[2] != '\0') {
                printf("Error BRnzp or varient expected else got %s", first);
            }
        }
        else if(thing[1] == 'p') {
            if (thing[2] != '\0') {
                printf("Error BRnzp or varient expected else got %s", first);
            }
        }
    }
    else if (thing[0] == 'z') {
        if (thing[1] == 'p') {
            if (thing[2] != '\0') {
                printf("Error BRnzp or varient expected else got %s", first);
            }
        }
        else if (thing[1] != '\0') {
            printf("Error BRnzp or varient expected else got %s", first);
        }
    }
    else if (thing[0] == 'p') {
        if (thing[1] != '\0') {
            printf("Error BRnzp or varient expected else got %s", first);
        }
    }
    first = strtok(NULL, " ,;");
    //get rid of \n at end if there is one.
    int len = (int)strlen(first);
    if (first[len-1] == '\n') {
        first[len-1] = '\0';
    }
    if (!checkSymbols(first)) {
        printf("Unspecified Symbol %s\n", first);
    }
}
void ldSyntaxCheck(char *first) {
    first = strtok(NULL, " ,;");
    char integer[30];
    int length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    
    int number = atoi(integer);
    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    
    first = strtok(NULL, " ,;");
    //get rid of \n at end if there is one.
    int len = (int)strlen(first);
    if (first[len-1] == '\n') {
        first[len-1] = '\0';
    }
    if (!checkSymbols(first)) {
        printf("Unspecified Symbol %s at Line Number %d\n", first, program_counter);
    }
}
void ldrSyntaxCheck(char *first) {
    first = strtok(NULL, " ,;\n");
    char integer[30];
    int length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    
    int number = atoi(integer);
    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    first = strtok(NULL, " ,;\n");
    length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    
    number = atoi(integer);
    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    char *integer2 = strtok(first, "#");
    number = atoi(integer2);
    if (number < -16 || number > 15) { printf("%d cannot be represented as a signed number in 5 bits  at Line Number: %d", number, program_counter);}//end #
    
}
void notSyntaxCheck(char *first) {
    first = strtok(NULL, " ,;\n");
    char integer[30];
    int length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    
    int number = atoi(integer);
    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    first = strtok(NULL, " ,;\n");
    length = 0;
    while (first[length+1] != '\0')
    {
        integer[length] = first[length+1];
        length++;
    }
    integer[length] = '\0';
    if(strlen(first) != 2) {
        printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);
    }
    
    number = atoi(integer);
    if (first[0] != 'R' || number < 0 || number > 7 ) {printf("Expected R0-7 but found %s at Line Number: %d\n", first, program_counter);}
    
}
void trapSyntaxCheck(char *first) {
    char *integer2 = strtok(NULL, " #");
    int number = atoi(integer2);
    if (number < 0 || number > 255) { printf("%d cannot be represented as a signed number in 8 bits  at Line Number: %d", number, program_counter);}//end #
    
}
void origSyntaxCheck(char *first) {
    
    /*
     Get the Origin of the File
     */
    first = strtok(NULL, " x,;\n");
    int number = atoi(first);
    if (number < 0x0200 || number > 0xFE00)
    {
        printf("Expected Valid Hex value instead got %d", number);
    }
    else {
        origin = number;
    }
    
}
void fillSyntaxCheck(char *first) {
    first = strtok(NULL, " \n,;");
    if ((first[0] != '0' && first[0] != 'x') || (first[0] != 'x' && first[0] != '0')) {
        if (!checkSymbols(first)) {
            printf("Label expected instead got %s", first);
        }
    }
    else {
        char integer[30];
        if (first[0] == '0') {
            int length = 0;
            while (first[length+2] != '\0')
            {
                integer[length] = first[length+2];
                length++;
            }
            integer[length] = '\0';
            
        }
        else if (first[0] == 'x') {
            int length = 0;
            while (first[length+1] != '\0')
            {
                integer[length] = first[length+1];
                length++;
            }
            integer[length] = '\0';
            
        }
        
        //first = strtok(NULL, " #x\n;,");
        int number = atoi(integer);
        if (number < -32768 || number > 65535)
        {
            printf("Expected Valid value instead got %d", number);
        }
    }
}
void blkwSyntaxCheck(char *first) {
    first = strtok(NULL, " \n,;");
    if ((first[0] != '0' && first[0] != 'x') || (first[0] != 'x' && first[0] != '0')) {
        //first = strtok(NULL, " #x\n;,");
        int number = atoi(first);
        if (number < -32768 || number > 65535)
        {
            printf("Expected Valid value instead got %d", number);
        }
        return;
    }
    else {
        char integer[30];
        if (first[0] == '0') {
            int length = 0;
            while (first[length+2] != '\0')
            {
                integer[length] = first[length+2];
                length++;
            }
            integer[length] = '\0';
            
        }
        else if (first[0] == 'x') {
            int length = 0;
            while (first[length+1] != '\0')
            {
                integer[length] = first[length+1];
                length++;
            }
            integer[length] = '\0';
            
        }
        
        //first = strtok(NULL, " #x\n;,");
        int number = atoi(integer);
        if (number < -32768 || number > 65535)
        {
            printf("Expected Valid value instead got %d\n", number);
        }
    }
}
void stringzSyntaxCheck(char *first) {
    first = strtok(NULL, " \n,;");
    if (first[0] != '\"') {
        printf("Expected String instead got %s at Line Number %d\n", first, program_counter);
    }
    int length = 0;
    while (first[length] != '\0') {
        length++;
    }
    if (first[length-1] != '\"') {
        printf("Expected String instead got %s at Line Number %d\n", first, program_counter);
    }
}
/*
 This executes the addition command in the lc3
 */
void addFunction(char *first)
{
    short number = 1;
    number = number<<12;
    first = strtok(NULL, "R ,;");
    int DR = atoi(first);
    DR = DR<<9;
    number += DR;
    first = strtok(NULL, "R ,;");
    DR = atoi(first);
    DR = DR<<6;
    number += DR;
    first = strtok(NULL, " ,;");
    if (first[0] == 'R') {
        DR = atoi(first);
    }else{
        DR = 1;
        DR<<=5;
        number += DR;
        DR = atoi(first);
    }
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void andFunction(char *first)
{
    short number = 5;
    number = number<<12;
    first = strtok(NULL, "R ,;");
    int DR = atoi(first);
    DR = DR<<9;
    number += DR;
    first = strtok(NULL, "R ,;");
    DR = atoi(first);
    DR = DR<<6;// SR1
    number += DR;
    DR = 1;
    DR = DR<<5; // PLACE 1 in bit 5
    number += DR;
    first = strtok(NULL, "R ,;");
    DR = atoi(first);
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);   
}
/*
 This executes the BR command in the lc3
 */
void brFunction(char *first)
{
    char copy[6];
    unsigned short number = 0;
    unsigned int value = 8;
    strcpy(copy, first);
    if(strlen(copy) == 2) { //BR with no specified nzp means it's unconditional
        value = value << 9;
        number += value;
    } else {
        for (int i = 2; i < strlen(copy); i++) {
            
            switch (copy[i]) {
                case 'n':
                    value = 1;
                    value = value << 11;
                    number += value;
                    break;
                case 'z':
                    value = 1;
                    value = value << 10;
                    number += value;
                    break;
                case 'p':
                    value = 1;
                    value = value << 9;
                    number += value;
                    break;
                default:
                    printf("Invalid OPCODE"); // this should never occur
                    break;
            }
        }
    }
    first = strtok(NULL, " ,;\n");
    unsigned short offset = 0;
    if (checkSymbols(first)) {
        short label_pos = getItem(&word_library, getItemIndex(&word_library, first))->line_number;
        origin = origin >> 8 | origin << 8;
        offset = label_pos - program_counter;
        if (offset < 0) {
            value = offset - 64512;
        }
        else {
            value = offset;
        }
    }
    else {
        value = atoi(first); // get Offset
    }
    
    number += value;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void jmpFunction(char *first)
{
    short number = 12;
    number = number << 12;
    first = strtok(NULL, "R ,;");
    int DR = atoi(first);
    DR = DR<<6;
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void jsrFunction(char *first)
{
    short number = 4;
    number = number << 12;
    int value = 1;
    value = value << 11; // place 1 in bit 11 for JSR
    number += value;
    first = strtok(NULL, " ,;\n");
    short offset = 0;
    if (checkSymbols(first)) {
        short label_pos = getItem(&word_library, getItemIndex(&word_library, first))->line_number;
        origin = origin >> 8 | origin << 8;
        offset = label_pos - program_counter;
        if (offset < 0) {
            value = offset - 63488;
        }
        else {
            value = offset;
        }
    }
    else {
        value = atoi(first); // get Offset
    }
    
    number += value;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void jsrrFunction(char *first)
{
    short number = 4;
    number = number << 12;
    int value = 0;
    first = strtok(NULL, "R ,;");
    value = atoi(first); // get BaseR
    value = value << 6;  // Place in bits 8-6
    number += value;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void ldFunction(char *first)
{
    short number = 2;
    number = number << 12;
    int DR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    first = strtok(NULL, " ,;\n");
    short offset = 0;
    if (checkSymbols(first)) {
        short label_pos = getItem(&word_library, getItemIndex(&word_library, first))->line_number;
        origin = origin >> 8 | origin << 8;
        offset = label_pos - program_counter;
        if (offset < 0) {
            DR = offset - 64512;
        }
        else {
            DR = offset;
        }
    }
    else {
        DR = atoi(first); // get Offset
    }
    
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void ldiFunction(char *first)
{
    unsigned short number = 10;
    number = number << 12;
    unsigned int DR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    DR++;
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    first = strtok(NULL, " ,;\n");
    unsigned short offset = 0;
    if (checkSymbols(first)) {
        short label_pos = getItem(&word_library, getItemIndex(&word_library, first))->line_number;
        offset = label_pos - program_counter;
        if (offset < 0) {
            DR = offset + 64512;
        }
        else {
            DR = offset;
        }
    }
    else {
        DR = atoi(first); // get Offset
    }
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void ldrFunction(char *first)
{
    short number = 6;
    number = number << 12;
    int DR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get BaseR
    DR = DR << 6;  // Place in bits 8-6
    number += DR;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get Offset
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void leaFunction(char *first)
{
    unsigned short number = 14;
    number = number << 12;
    unsigned int DR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    DR++;
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    first = strtok(NULL, " ,;\n");
    unsigned short offset = 0;
    if (checkSymbols(first)) {
        short label_pos = getItem(&word_library, getItemIndex(&word_library, first))->line_number;
        offset = label_pos - program_counter;
        if (offset < 0) {
            DR = offset + 64512;
        }
        else {
            DR = offset;
        }
    }
    else {
        DR = atoi(first); // get Offset
    }
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void notFunction(char *first)
{
    short number = 9;
    number = number << 12;
    int DR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get SR
    DR = DR << 6;  // Place in bits 8-6
    number += DR;
    first = strtok(NULL, "R ,;");
    DR = 63; //fill bits 5 - 0 with 1's
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void retFunction(char *first)
{
    short number = 12;
    number = number << 12;
    int value = 7; // set BaseR to R7
    value = value << 6;  // Place in bits 8-6
    number += value;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void rtiFunction(char *first)
{
    short number = 1;
    number = number << 15;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void stFunction(char *first)
{
    short number = 3;
    number = number << 12;
    int DR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    first = strtok(NULL, " ,;\n");
    short offset = 0;
    if (checkSymbols(first)) {
        short label_pos = getItem(&word_library, getItemIndex(&word_library, first))->line_number;
        origin = origin >> 8 | origin << 8;
        offset = label_pos - program_counter;
        if (offset < 0) {
            DR = offset - 64512;
        }
        else {
            DR = offset;
        }
    }
    else {
        DR = atoi(first); // get Offset
    }
    
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void stiFunction(char *first)
{
    unsigned short number = 11;
    number = number << 12;
    unsigned int DR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    DR++;
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    first = strtok(NULL, " ,;\n");
    unsigned short offset = 0;
    if (checkSymbols(first)) {
        short label_pos = getItem(&word_library, getItemIndex(&word_library, first))->line_number;
        offset = label_pos - program_counter;
        if (offset < 0) {
            DR = offset + 64512;
        }
        else {
            DR = offset;
        }
    }
    else {
        DR = atoi(first); // get Offset
    }
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in the lc3
 */
void strFunction(char *first)
{
    short number = 7;
    number = number << 12;
    int SR = 0;
    first = strtok(NULL, "R ,;");
    SR = atoi(first); // get DR
    SR = SR << 9;  // Place in bits 11-9
    number += SR;
    first = strtok(NULL, "R ,;");
    SR = atoi(first); // get BaseR
    SR = SR << 6;  // Place in bits 8-6
    number += SR;
    first = strtok(NULL, "R ,;");
    SR = atoi(first); // get Offset
    number += SR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
/*
 This executes the and command in t     he lc3
 */
void trapFunction(char *first)
{
    unsigned short number = 15;
    number = number << 12;
    unsigned int TRAP = 0; // get Trapvector
    sscanf(first, "%x", &TRAP);
    number += TRAP;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
}
void pushFunction(char *first)
{
    //add
    unsigned short number = 1;
    number = number<<12;
    unsigned int DR = 6;
    DR = DR<<9;
    number += DR;
    DR = 6;
    DR = DR<<6;
    number += DR;
    DR = -1;
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
    program_counter++;
    //STR
    number = 7;
    number = number << 12;
    int SR = 0;
    first = strtok(NULL, "R ,;");
    SR = atoi(first); // get DR
    SR = SR << 9;  // Place in bits 11-9
    number += SR;
    SR = 6; // get BaseR
    SR = SR << 6;  // Place in bits 8-6
    number += SR;
    SR = 0; // get Offset
    number += SR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
    
}
void popFunction(char *first)
{
    //LDR
    unsigned short number = 6;
    number = number << 12;
    unsigned int DR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    DR = 6; // get BaseR
    DR = DR << 6;  // Place in bits 8-6
    number += DR;
    DR = 0; // get Offset
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
    program_counter++;
    
    //add
    number = 1;
    number = number<<12;
    DR = 6;
    DR = DR<<9;
    number += DR;
    DR = 6;
    DR = DR<<6;
    number += DR;
    DR = 1;
    number += DR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
    
}
void negFunction(char *first)
{
    short number = 9;
    number = number << 12;
    int DR = 0;
    int SR = 0;
    first = strtok(NULL, "R ,;");
    DR = atoi(first); // get DR
    int ODR = DR;
    DR = DR << 9;  // Place in bits 11-9
    number += DR;
    first = strtok(NULL, "R ,;");
    SR = atoi(first); // get SR
    SR = SR << 6;  // Place in bits 8-6
    number += SR;
    first = strtok(NULL, "R ,;");
    SR = 63; //fill bits 5 - 0 with 1's
    number += SR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
    program_counter++;
    
    //add
    number = 1;
    number = number<<12;
    SR = ODR;
    SR = SR<<9;
    number += SR;
    SR = ODR;
    SR = SR<<6;
    number += SR;
    SR = 1;
    SR<<=5;
    number += SR;
    SR = 1;
    number += SR;
    number = number >> 8 | number << 8;
    fwrite(&number, sizeof(short), 1, output_file);
    
    
}
void blkwFunction(char *first) 
{
    int space = 0;
    int number = 0;
    first = strtok(NULL, "#x ,;\n");
    sscanf(first, "%d",&space);
    for (int i = 0; i < space; i++) {
        fwrite(&number, sizeof(short), 1, output_file);
    }
}
void stringzFunction(char *first) 
{
    int space = 0;
    int number = 0;
    first = strtok(NULL, "#x ,;\n");
    int i = 1;
    while (first[i] != '\0') {
        fwrite(&first[i], sizeof(char), 1, output_file);
        i++;
    }
    fwrite(&number, sizeof(char), 1, output_file);
}
void fillFunction(char *first) 
{
    first = strtok(NULL, "# ,;\n");
    int number = 0;
    if (checkSymbols(first)) {
        short label_pos = getItem(&word_library, getItemIndex(&word_library, first))->line_number + origin;
        fwrite(&label_pos, sizeof(char), 1, output_file);
    }
    else {
        sscanf(first, "%x", &number);
        fwrite(&number, sizeof(char), 1, output_file);
    }
}
void origFunction(char *first)
{
    char *message = strtok(NULL, " ,;");
    if (message[0] == 'x')
    {
        char temp[30];
        int length = 0;
        while (message[length] != '\0')
        {
            length++;
        }
        for (int i = 0; i<= length; i++)
        {
            temp[i] = message[i+1];
        }
        //set origin to the passed in number
        sscanf(temp, "%x", &origin);
    }
    else
    {
        //set origin to the passed in number
        sscanf(message, "%X", &origin);
    }
    if (origin < 0x0200 || origin > 0xFE00)
    {
        if (origin == 0) {
            printf("Please put 0 in front of x\n");
        }
        else {
            printf("Expected Valid Hex value instead got %d at Line Number %d\n", origin, program_counter);
        }
    }
}